package cn.szabadsag.user.service.impl;

import cn.szabadsag.base.constant.WxConstant;
import cn.szabadsag.user.domain.LoginInfo;
import cn.szabadsag.user.domain.User;
import cn.szabadsag.user.domain.WxUser;
import cn.szabadsag.user.mapper.LoginInfoMapper;
import cn.szabadsag.user.mapper.UserMapper;
import cn.szabadsag.user.mapper.WxUserMapper;
import cn.szabadsag.user.service.IWxUserService;
import cn.szabadsag.utils.AjaxResult;
import cn.szabadsag.utils.HttpClientUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @author yangcong
 * @date 2022年03月13日 13:11
 * @since
 */
@Service
@Transactional(readOnly = true,propagation = Propagation.SUPPORTS)
public class WxUserServiceImpl implements IWxUserService {
    
    @Autowired
    private WxUserMapper wxUserMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private LoginInfoMapper loginInfoMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 微信登录
     * @param map
     * @return
     */
    @Override
    @Transactional
    public AjaxResult wxLogin(Map<String, String> map) {
        //  通过code获取access_token
        String code = map.get("code");

        //  发送请求的链接
        String url = WxConstant.ACCESS_TOKEN_URL
                .replace("APPID", WxConstant.APPID)
                .replace("SECRET", WxConstant.SECRET)
                .replace("CODE", code);

        //  发送请求
        String result = HttpClientUtils.httpGet(url);
        //System.out.println(result);
        /*
        {
            "access_token": "54_cU_EhlNUiaa4POKxMc5oKEaKaFdcMOykiz-2ySif_b27FYLCGoIwgI_DxCTbz8iLSA4mBCtQA9ZCL9l_ZlVqhxCeq0Opo4cIB3QjeB8X0xs",
            "expires_in": 7200,
            "refresh_token": "54_IiuOqG5ehnd0V7GB_ucta1ET-XnJtzJwAr1WboyWb4KBEZxQUb8TeeJFRPoLxEAQgOvRXdWSf9Bq6FQYJ5eMVB9OiUKGe5Bmv7Ww_q_J3E8",
            "openid": "oa9wA02vW-ya11xRr59nHkAu-6ZQ",
            "scope": "snsapi_login",
            "unionid": "ovnCWw2p2iH386hnX7BuPMbC3YAU"
        }
         */
        //  解析数据(使用alibaba的fastjson解析数据，将文本转化为对象)
        JSONObject jsonObject = JSON.parseObject(result);
        //  获取access_token
        String access_token = jsonObject.getString("access_token");
        //  获取openid
        String openid = jsonObject.getString("openid");

        System.out.println("openid:" + openid);

        //  查询wxuser
        WxUser wxUser = wxUserMapper.loadByOpenid(openid);
        if(wxUser!=null){
            //  老用户
            //  查询t_user
            User user = userMapper.loadById(wxUser.getUser_id());
            //  查询t_logininfo
            LoginInfo loginInfo = loginInfoMapper.loadById(user.getLogininfo_id());
            //  免密登录
            return noPwdLogin(loginInfo);

        }else {
            //  新用户
            String redirectUri = "/binder.html?access_token=" + access_token + "&openid=" + openid;
            return AjaxResult.me().setSuccess(false).setResultObj(redirectUri);
        }
    }

    /**
     * 微信新用户绑定
     * @param map:phone,code,codeType="BINDER",access_token,openid
     * @return
     */
    @Override
    @Transactional
    public AjaxResult bind(Map<String, String> map) {

        String phone = map.get("phone");
        String code = map.get("code");
        String codeType = map.get("codeType");
        String access_token = map.get("access_token");
        String openid = map.get("openid");


        //  判断验证码code是否正确
        String codeInRedis = (String)redisTemplate.opsForValue().get(phone + ":" + codeType);
        if (codeInRedis == null) {
            return AjaxResult.me().setMessage("验证码错误！");
        }
        if (!codeInRedis.split(":")[0].equals(code)) {
            return AjaxResult.me().setMessage("验证码错误！");
        }
        
        //  获取微信用户个人信息
        String url = WxConstant.WXUSER_INFO
                .replace("ACCESS_TOKEN",access_token)
                .replace("OPENID",openid);
        String result = HttpClientUtils.httpGet(url);
        System.out.println("微信新用户" + result);
        /*
        {
            "openid": "oa9wA02vW-ya11xRr59nHkAu-6ZQ",
            "nickname": ".",
            "sex": 0,
            "language": "",
            "city": "",
            "province": "",
            "country": "",
            "headimgurl": "https:\/\/thirdwx.qlogo.cn\/mmopen\/vi_32\/W4M3b0cacrRHuG9iaibZqnFbyjo5ZHKf69Noib0P4Bic8QKnrQek3SHGRpehkQHYAEctBZhjTJbLy9Z8iaYWgQqIbpg\/132",
            "privilege": [],
            "unionid": "ovnCWw2p2iH386hnX7BuPMbC3YAU"
        }
         */
        //  解析数据
        JSONObject jsonObject = JSON.parseObject(result);
        //  生成微信新用户
        WxUser wxUser = new WxUser();
        wxUser.setOpenid(jsonObject.getString("openid"));
        wxUser.setNickname(jsonObject.getString("nickname"));
        wxUser.setSex(jsonObject.getInteger("sex"));
        wxUser.setHeadimgurl(jsonObject.getString("headimgurl"));
        wxUser.setUnionid(jsonObject.getString("unionid"));
        //  根据手机号查询用户是否注册过
        User user = userMapper.loadByPhone(phone);
        LoginInfo loginInfo = null;
        if(user == null){
            //  新用户==>生成t_user,t_logininfo==>免密登录
            user = new User();
            user.setUsername(jsonObject.getString("nickname"));
            user.setPhone(phone);
            user.setState(1);
            user.setCreatetime(new Date());

            loginInfo = new LoginInfo();
            BeanUtils.copyProperties(user,loginInfo);
            loginInfo.setType(1);
            loginInfo.setDisable(1);
            //  保存logininfo
            loginInfoMapper.save(loginInfo);
            user.setLogininfo_id(loginInfo.getId());
            userMapper.save(user);
        }else {
            //  用户已注册==>免密登录
            loginInfo = loginInfoMapper.loadByAccount(phone);
        }
        //  把用户表和和微信表绑定
        wxUser.setUser_id(user.getId());
        //  保存微信用户表的数据
        wxUserMapper.save(wxUser);
        //  免密登录
        return noPwdLogin(loginInfo);
    }

    /**
     * 免密登录
     * @param loginInfo
     */
    private AjaxResult noPwdLogin(LoginInfo loginInfo) {
        //  生成token
        String token = UUID.randomUUID().toString();
        //  把当前登录用户存储在redis中
        redisTemplate.opsForValue().set(token,loginInfo,30, TimeUnit.MINUTES);
        //  将token和登录信息返回给前端
        HashMap<String, Object> map = new HashMap<>();
        //  清除敏感数据
        loginInfo.setPassword("");
        loginInfo.setSalt("");
        map.put("token",token);
        map.put("loginInfo",loginInfo);
        //  将token和登录信息返回给前端
        return AjaxResult.me().setResultObj(map);
    }
}
